<?php
/**
 * 配置读取类
 * 路径格式：
 * 主模块 - ".category.key"
 * 辅模块 - "module.category.key"
 *
 * @author ananda
 */
class Config extends Component implements ArrayAccess
{
    public $base_dir;
    public $conf_dir;

    protected $data = array();

    public function init() {
        $this->base_dir = CROOT.Com::glob('com.dir.module');
        $this->conf_dir = Com::glob('com.dir.conf');
    }

    /**
     * ArrayAccess接口
     * 与正常思路不同，未载入的配置被定义为不存在
     * @param <string> $offset
     * @return <boolean>
     */
    public function offsetExists($offset)
    {
        // 确定读取模块和分类
        $route = $this->route($offset);
        if (!isset($this->data[$route['module']][$route['category']])) {
            return false;
        }
        $conf = $this->data[$route['module']][$route['category']];

        // 返回值
        if ($rount['key']) {
            return isset($conf[$rount['key']]);
        }
        return true;
    }

    /**
     * ArrayAccess接口
     * 这个是正常的读取配置操作
     * 如果配置未载入则从文件载入，载入后则直接返回
     * @param <string> $offset
     * @return <mixed>
     */
    public function offsetGet($offset)
    {
        $route = $this->route($offset);
        if (!isset($this->data[$route['module']][$route['category']])) {
            $this->data[$route['module']][$route['category']] = require $this->getPath($module, $category);
        }
        $conf = $this->data[$route['module']][$route['category']];

        // 返回值
        if ($rount['key']) {
            return $conf[$rount['key']];
        }
        return $conf;
    }

    /**
     * ArrayAccess接口
     * 同样作用有所不同，这里是允许直接给某个配置路径设置值
     * 如果该路径有文件对应的配置，在设值后则不会读取文件中的配置了
     * @param <string> $offset
     * @param <string> $value
     */
    public function offsetSet($offset, $value)
    {
        $route = $this->route($offset);
        if ($rount['key']) {
            $this->data[$route['module']][$route['category']][$rount['key']] = $value;
        } else {
            $this->data[$route['module']][$route['category']] = $value;
        }
    }

    /**
     * ArrayAccess接口
     * 注销掉一个已经载入内存的配置
     * @param <string> $offset
     */
    public function offsetUnset($offset)
    {
        $route = $this->route($offset);
        if ($rount['key']) {
            unset($this->data[$route['module']][$route['category']][$rount['key']]);
        } else {
            unset($this->data[$route['module']][$route['category']]);
        }
    }

    /**
     * 对配置路径进行解析
     * @param <string> $path
     * @return <array>
     */
    public function route($path)
    {
        $path  = explode('.', $path);
        $route = array();
        if (!$path[0]) {
            $route['module'] = Com::glob('com.module');
        } else {
            $route['module'] = trim($path[0]);
        }
        $route['category'] = $path[1];

        unset($path[0]);
        unset($path[1]);
        $route['key'] = implode('.', $path);

        return $route;
    }

    /**
     * 获取模块分类文件路径
     * @param string $module
     * @param string $category
     * @return <string>
     */
    public function getPath($module, $category)
    {
        return $this->base_dir.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR.
               $this->conf_dir.DIRECTORY_SEPARATOR."$category.php";
    }
}
